#ifndef DEM_READER_H
#define DEM_READER_H

#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <iostream>
#include <cmath>

// 地理点类
struct GeoPoint {
    double longitude;  // 经度
    double latitude;   // 纬度
    double elevation;  // 高程
    
    GeoPoint(double lon = 0.0, double lat = 0.0, double elev = 0.0)
        : longitude(lon), latitude(lat), elevation(elev) {}
};

// DEM读取器类
class DemReader {
public:
    DemReader();
    ~DemReader();
    
    // 从文件加载DEM数据
    bool loadDemData(const std::string& filePath);
    
    // 根据经纬度计算高程
    double calculateElevation(double longitude, double latitude);
    
    // 检查数据是否加载
    bool isDataLoaded() const { return dataLoaded; }
    
    // 获取数据信息
    void getDataInfo(int& ncols, int& nrows, double& xllcorner, double& yllcorner, double& cellsize) const {
        ncols = this->ncols;
        nrows = this->nrows;
        xllcorner = this->xllcorner;
        yllcorner = this->yllcorner;
        cellsize = this->cellsize;
    }

private:
    // 存储高程数据的容器
    std::vector<std::vector<double> > demData;
    
    // DEM数据参数
    int ncols;        // 列数
    int nrows;        // 行数
    double xllcorner; // 左下角经度
    double yllcorner; // 左下角纬度
    double cellsize;  // 单元格大小
    
    // 数据加载状态
    bool dataLoaded;  
    
    // 计算两点之间的距离
    static double calculateDistance(double lon1, double lat1, double lon2, double lat2);
    
    // 使用双线性插值计算高程
    // 双线性插值是一种在二维网格上估计未知点值的方法，其原理是：
    // 1. 确定包含目标点的四个相邻网格点
    // 2. 在目标点所在行的左右两个网格点之间进行线性插值
    // 3. 在两个横向插值结果之间进行线性插值，得到最终的高程值
    double bilinearInterpolation(double x, double y);
    
    // 将经纬度转换为网格坐标
    bool latLonToGrid(double longitude, double latitude, int& col, int& row);
};

#endif // DEM_READER_H